
from domain.models.models import  Message
from db.db import async_session
from sqlalchemy import func
from sqlalchemy.future import select
# 添加消息类型映射字典
MESSAGE_TYPE_MAP = {
    'activity': 1,
    'interaction': 2,
    'system': 3
}

async def get_user_messages(user_id: int, page: int = 1, page_size: int = 20, message_type: str = None) -> tuple[list, int]:
    """获取用户的消息，支持分页和消息类型过滤
    
    Args:
        user_id: 用户ID
        page: 页码，从1开始
        page_size: 每页消息数量
        message_type: 消息类型（'activity'/'interaction'/'system'），为None时返回所有类型
    
    Returns:
        tuple[list, int]: 返回消息列表和总消息数量
    """
    async with async_session() as session:
        try:
            # 计算偏移量
            offset = (page - 1) * page_size
            
            # 构建基础查询
            query = select(Message).where(
                Message.receiver_id == user_id
            )
            
            # 如果指定了消息类型，添加类型过滤条件
            if message_type and message_type in MESSAGE_TYPE_MAP:
                query = query.where(Message.type == MESSAGE_TYPE_MAP[message_type])
            
            # 添加排序条件
            query = query.order_by(
                Message.status.asc(),  # 未读消息优先
                Message.updated_at.desc()   # 按更新时间倒序
            )
            
            # 获取总数
            total_count = await session.scalar(
                select(func.count()).select_from(query.subquery())
            )
            
            # 获取分页数据
            result = await session.execute(
                query.offset(offset).limit(page_size)
            )
            messages = result.scalars().all()
            
            # 转换为字典列表
            message_list = [{
                'id': msg.id,
                'type': msg.type,
                'title': msg.title,
                'content': msg.content,
                'sender_id': msg.sender_id,
                'activity_id': msg.activity_id,
                'comment_id': msg.comment_id,
                'status': msg.status,
                'create_time': msg.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                'update_time': msg.updated_at.strftime('%Y-%m-%d %H:%M:%S')
            } for msg in messages]
            
            return message_list, total_count
            
        except Exception as e:
            raise e

async def insert_message(type: str, title: str, content: str, receiver_id: int, sender_id: int = None, 
                     activity_id: int = None, comment_id: int = None) -> int:
    """插入一条消息记录
    
    Args:
        type: 消息类型（'activity'-活动消息，'interaction'-互动消息，'system'-系统消息）
        title: 消息标题
        content: 消息内容
        receiver_id: 接收者ID
        sender_id: 发送者ID（可选，系统消息可为空）
        activity_id: 相关活动ID（可选）
        comment_id: 相关评论ID（可选）
    
    Returns:
        int: 新插入消息的ID
        
    Raises:
        ValueError: 当消息类型不在预定义类型中时抛出
    """
    if type not in MESSAGE_TYPE_MAP:
        raise ValueError(f"Invalid message type: {type}. Must be one of: {', '.join(MESSAGE_TYPE_MAP.keys())}")
        
    async with async_session() as session:
        try:
            # 创建新的消息对象
            new_message = Message(
                type=MESSAGE_TYPE_MAP[type],  # 将字符串类型转换为对应的整数
                title=title,
                content=content,
                sender_id=sender_id,
                receiver_id=receiver_id,
                activity_id=activity_id,
                comment_id=comment_id,
                status=0  # 初始状态为未读
            )
            
            # 添加到会话并提交
            session.add(new_message)
            await session.commit()
            
            # 刷新以获取新插入记录的ID
            await session.refresh(new_message)
            return new_message.id
            
        except Exception as e:
            print(e)
            await session.rollback()
            raise e
   
async def get_unread_message_counts(user_id: int) -> dict:
    """获取用户不同类型未读消息的数量
    
    Args:
        user_id: 用户ID
    
    Returns:
        dict: 包含各类型未读消息数量的字典，格式为：{1: 活动消息数量, 2: 互动消息数量, 3: 系统消息数量}
    """
    async with async_session() as session:
        try:
            # 查询各类型未读消息数量
            query = select(
                Message.type,
                func.count(Message.id).label('count')
            ).where(
                Message.receiver_id == user_id,
                Message.status == 0,  # 未读状态
            ).group_by(Message.type)
            
            result = await session.execute(query)
            unread_counts = {row.type: row.count for row in result}
            
            # 确保所有类型都有计数值
            message_types = [1, 2, 3]  # 1-活动消息，2-互动消息，3-系统消息
            return {msg_type: unread_counts.get(msg_type, 0) for msg_type in message_types}
            
        except Exception as e:
            raise e

async def update_message_status(message_ids: list, status: int = 1) -> bool:
    """更新消息状态
    
    Args:
        message_ids: 消息ID列表
        status: 消息状态（0未读，1已读）
    
    Returns:
        bool: 更新是否成功
    """
    async with async_session() as session:
        try:
            await session.execute(
                Message.__table__.update()
                .where(Message.id.in_(message_ids))
                .values(status=status)
            )
            await session.commit()
            return True
        except Exception as e:
            print(e)
            await session.rollback()
            return False